﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace SharpSoft.Net.Protocols
{
    /// <summary>
    /// 切片流，托管其他数据流的一部分
    /// </summary>
    public sealed class SectionStream : Stream
    {
        public SectionStream(Stream stream, long pos, long length)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream), "被托管的数据流不能为null。");
            }
            section_position = pos;
            section_length = length;
            BaseStream = stream;
        }
        public Stream BaseStream { get; private set; }
        private long section_position, section_length;
        private long position = 0;
        public override bool CanRead => BaseStream.CanRead;

        public override bool CanSeek => BaseStream.CanSeek;

        public override bool CanWrite => BaseStream.CanWrite;

        public override long Length => section_length;

        public override long Position { get => position; set { position = value; } }



        public override void Flush()
        {
            BaseStream.Flush();
        }
        private int readedcount = 0;
        public override int Read(byte[] buffer, int offset, int count)
        {
            if (readedcount >= section_length)
            {//已读取完毕
                return 0;
            }
            count = (int)Math.Min(count, section_length - readedcount);

            var rc = BaseStream.Read(buffer, offset, count);
            readedcount += rc;
            return rc;
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            switch (origin)
            {
                case SeekOrigin.Begin:
                    BaseStream.Seek(section_position + offset, SeekOrigin.Begin);
                    break;
                case SeekOrigin.Current:
                    BaseStream.Seek(offset, SeekOrigin.Current);
                    break;
                case SeekOrigin.End:
                    BaseStream.Seek(section_position + section_length - offset, SeekOrigin.Begin);
                    break;
                default:
                    break;
            }
            return Position;
        }

        public override void SetLength(long value)
        {
            section_length = value;
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            BaseStream.Write(buffer, offset, count);
        }
    }
}
